package com.lej.core.widget.letter

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import com.lej.core.R
import com.lej.core.dsl.background_res
import com.lej.core.utils.extention.getDrawableCompat
import com.lej.core.utils.extention.keepScope

class LetterIndexView @JvmOverloads constructor(
    paramContext: Context,
    paramAttributeSet: AttributeSet? = null,
    paramInt: Int = 0
) : View(paramContext, paramAttributeSet, paramInt) {
    private var listener: OnTouchingLetterChangedListener? = null
    private var letters = arrayOf(
        "↑", "@", "#", "A", "B", "C", "D", "E", "F", "G",
        "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
        "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
    )
    private val mPaint: Paint = Paint()
    private var offset: Float
    private var hit: Boolean
    private var normalColor: Int
    private val touchColor: Int
    private val hintDrawable: Drawable?
    fun setOnTouchingLetterChangedListener(onTouchingLetterChangedListener: OnTouchingLetterChangedListener?) {
        listener = onTouchingLetterChangedListener
    }

    fun setLetters(letters: Array<String>) {
        this.letters = letters
    }

    fun setNormalColor(color: Int) {
        normalColor = color
        mPaint.color = normalColor
    }

    override fun dispatchTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                hit = true
                background_res = R.color.def_letter_idx_bg
                mPaint.color = touchColor
                onHit(event.y)
            }
            MotionEvent.ACTION_MOVE -> onHit(event.y)
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> onCancel()
        }
        invalidate()
        return true
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val letterHeight = height.toFloat() / letters.size
        val width = width.toFloat()
        val textSize = letterHeight * 5 / 6
        mPaint.textSize = textSize
        for (i in letters.indices) {
            val halfWidth = width / 2
            val letterPosY = letterHeight * i + textSize
            canvas.drawText(letters[i], halfWidth, letterPosY, mPaint)
        }
        if (hit) {
            val halfWidth = getWidth() / 2
            val halfDrawWidth = hintDrawable!!.intrinsicWidth / 2
            val translateX = (halfWidth - halfDrawWidth).toFloat()
            val halfDrawHeight = (hintDrawable.intrinsicHeight / 2).toFloat()
            val translateY = offset - halfDrawHeight
            canvas.save()
            canvas.translate(translateX, translateY)
            hintDrawable.draw(canvas)
            canvas.restore()
        }
    }

    private fun onHit(offset: Float) {
        this.offset = offset
        if (hit) {
            val index = (offset / height * letters.size).toInt().keepScope(0, letters.size - 1)
            listener?.onHit(letters.getOrNull(index))
        }
    }

    private fun onCancel() {
        hit = false
        setBackgroundColor(Color.TRANSPARENT)
        mPaint.color = normalColor
        refreshDrawableState()
        listener?.onCancel()
    }

    interface OnTouchingLetterChangedListener {
        fun onHit(letter: String?)
        fun onCancel()
    }

    init {
        offset = 0.0f
        hit = false
        normalColor = Color.GRAY
        touchColor = Color.WHITE
        hintDrawable = paramContext.getDrawableCompat(R.drawable.ic_letter_view_hit_point)
        hintDrawable!!.setBounds(0, 0, hintDrawable.intrinsicWidth, hintDrawable.intrinsicHeight)
        mPaint.isAntiAlias = true
        mPaint.textAlign = Paint.Align.CENTER
        mPaint.color = normalColor
    }
}